#include "csgpatchnode.h"
#include "expression/bernstein.hpp"
#include "bezier.h"
#include "CSG/csgfactory.h"

#include "../gl2ps.h"

#include "GL/glu.h"

::numeric::Interval<double>::self domain_u = ::numeric::Hull(0, 1);
::expression::Variable CSGPatchNode::u("u", domain_u);
::expression::Expression CSGPatchNode::expr_u = u.getSymbol();

::numeric::Interval<double>::self domain_v = ::numeric::Hull(0, 1);
::expression::Variable CSGPatchNode::v("v", domain_v);
::expression::Expression CSGPatchNode::expr_v = v.getSymbol();

const int numOfUPts = 10;
const int numOfVPts = 20;

CSGPatchNode::CSGPatchNode()
    : CSGNode(0), Bezier()
{
    numOfPatchPts = numOfUPts * numOfVPts;
    patchPts = NULL;

    constraints = NULL;
}

CSGPatchNode::CSGPatchNode(int *_ctrlPoly, double **_ctrlPts, CSGNode *parent)
    : CSGNode(0, parent), Bezier(2, 2, _ctrlPoly, _ctrlPts)
{
    patchPts = NULL;

    numOfPatchPts = numOfUPts * numOfVPts;
    patchPts = NULL;

    constraints = NULL;
}

CSGPatchNode::CSGPatchNode(int *_ctrlPoly, double **_ctrlPts, Expression &c, CSGNode *parent)
    : CSGNode(0, parent), Bezier(2, 2, _ctrlPoly, _ctrlPts)
{
    patchPts = NULL;

    numOfPatchPts = numOfUPts * numOfVPts;
    patchPts = NULL;

    constraints = NULL;

    addConstraint(c);
}

CSGPatchNode::~CSGPatchNode()
{
    if (patchPts)
    {
        for (int i = 0; i < numOfPatchPts; i++)
        {
            delete []patchPts[i];
        }

        delete []patchPts;
        patchPts = NULL;
    }

    if (constraints)
    {
        delete constraints;
    }
}

void CSGPatchNode::addConstraint(Expression& expr)
{
    constraints = new CSGPrimitiveNode(expr, NULL);
    StarTestBox box(0, 1, 0, 1);
    constraints->initial(box);

//    std::vector<Box*> bdBoxes;
//    constraints->getInitialResult(bdBoxes, BOX_BOUNDARY);
//    getBdPatches(bdBoxes);
}
